/*     */ package com.zimbra.cs.imap;
/*     */ 
/*     */ import com.zimbra.common.io.TcpServerInputStream;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import java.io.IOException;
/*     */ import java.util.List;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ final class TcpImapRequest
/*     */   extends ImapRequest
/*     */ {
/*     */   private TcpServerInputStream input;
/*     */   
/*     */   final class ImapContinuationException
/*     */     extends ImapParseException
/*     */   {
/*     */     private static final long serialVersionUID = 7925400980773927177L;
/*     */     boolean sendContinuation;
/*     */     
/*     */     ImapContinuationException(boolean send)
/*     */     {
/*  33 */       this.sendContinuation = send;
/*     */     }
/*     */   }
/*     */   
/*  37 */   private long literalCounter = -1L;
/*     */   private boolean unlogged;
/*  39 */   private long requestSize = 0L;
/*  40 */   private boolean maxRequestSizeExceeded = false;
/*     */   
/*     */   TcpImapRequest(TcpServerInputStream input, ImapHandler handler) {
/*  43 */     super(handler);
/*  44 */     this.input = input;
/*     */   }
/*     */   
/*     */   private void checkSize(long size) throws ImapParseException {
/*  48 */     int maxLiteralSize = Integer.MAX_VALUE;
/*  49 */     if (isAppend()) {
/*     */       try {
/*  51 */         long msgLimit = this.mHandler.getConfig().getMaxMessageSize();
/*  52 */         if ((msgLimit != 0L) && (msgLimit < maxLiteralSize) && 
/*  53 */           (size > msgLimit)) {
/*  54 */           throwSizeExceeded("message");
/*     */         }
/*     */       }
/*     */       catch (ServiceException se) {
/*  58 */         ZimbraLog.imap.warn("unable to check zimbraMtaMaxMessageSize", se);
/*     */       }
/*     */     }
/*  61 */     if ((isMaxRequestSizeExceeded()) || (size > maxLiteralSize)) {
/*  62 */       throwSizeExceeded("request");
/*     */     }
/*     */   }
/*     */   
/*     */   private void throwSizeExceeded(String exceededType) throws ImapParseException {
/*  67 */     if ((this.tag == null) && (this.index == 0) && (this.offset == 0)) {
/*  68 */       this.tag = readTag();rewind();
/*     */     }
/*  70 */     throw new ImapParseException(this.tag, "maximum " + exceededType + " size exceeded", true);
/*     */   }
/*     */   
/*     */   void continuation() throws IOException, ImapParseException {
/*  74 */     if (this.literalCounter >= 0L) {
/*  75 */       continueLiteral();
/*     */     }
/*     */     
/*  78 */     String line = this.input.readLine();
/*  79 */     String logline = line;
/*     */     
/*  81 */     if (line == null)
/*  82 */       throw new ImapTerminatedException();
/*  83 */     incrementSize(line.length());
/*  84 */     addPart(line);
/*     */     
/*  86 */     if ((this.parts.size() == 1) && (!this.maxRequestSizeExceeded))
/*     */     {
/*  88 */       this.unlogged = isLogin();
/*  89 */       if (this.unlogged) {
/*  90 */         logline = line.substring(0, line.indexOf(' ') + 7) + "...";
/*     */       }
/*     */     }
/*     */     
/*  94 */     ZimbraLog.imap.trace("C: %s", new Object[] { logline });
/*     */     
/*     */ 
/*  97 */     if ((line.endsWith("+}")) && (extensionEnabled("LITERAL+"))) {
/*  98 */       int openBrace = line.lastIndexOf('{', line.length() - 3);
/*  99 */       if (openBrace >= 0) {
/*     */         long size;
/*     */         try {
/* 102 */           size = Long.parseLong(line.substring(openBrace + 1, line.length() - 2));
/*     */         } catch (NumberFormatException nfe) {
/* 104 */           size = -1L;
/*     */         }
/* 106 */         if (size >= 0L) {
/* 107 */           if (!isAppend()) {
/* 108 */             incrementSize(size);
/*     */           }
/* 110 */           checkSize(size);
/* 111 */           this.literalCounter = size;
/* 112 */           continuation();
/*     */         } else {
/* 114 */           if ((this.tag == null) && (this.index == 0) && (this.offset == 0)) {
/* 115 */             this.tag = readTag();
/* 116 */             rewind();
/*     */           }
/* 118 */           throw new ImapParseException(this.tag, "malformed nonblocking literal");
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   private void continueLiteral() throws IOException, ImapParseException {
/* 125 */     if (this.maxRequestSizeExceeded) {
/* 126 */       long skipped = this.input.skip(this.literalCounter);
/* 127 */       if ((this.literalCounter > 0L) && (skipped == 0L)) {
/* 128 */         throw new ImapTerminatedException();
/*     */       }
/* 130 */       this.literalCounter -= skipped;
/*     */     } else {
/* 132 */       ImapRequest.Part part = (ImapRequest.Part)this.parts.get(this.parts.size() - 1);
/*     */       Literal literal;
/* 134 */       Literal literal; if (part.isLiteral()) {
/* 135 */         literal = part.getLiteral();
/*     */       } else {
/* 137 */         literal = Literal.newInstance((int)this.literalCounter, isAppend());
/* 138 */         addPart(literal);
/*     */       }
/* 140 */       int read = literal.copy(this.input);
/* 141 */       if (read == -1) {
/* 142 */         throw new ImapTerminatedException();
/*     */       }
/* 144 */       if ((!this.unlogged) && (ZimbraLog.imap.isTraceEnabled())) {
/* 145 */         ZimbraLog.imap.trace("C: {%s}", new Object[] { Integer.valueOf(read) });
/*     */       }
/* 147 */       this.literalCounter -= read;
/*     */     }
/* 149 */     if (this.literalCounter > 0L) {
/* 150 */       throw new ImapContinuationException(false);
/*     */     }
/* 152 */     this.literalCounter = -1L;
/*     */   }
/*     */   
/*     */   private Literal getCurrentBuffer() throws ImapParseException {
/* 156 */     return ((ImapRequest.Part)this.parts.get(this.index)).getLiteral();
/*     */   }
/*     */   
/*     */   protected Literal readLiteral() throws IOException, ImapParseException
/*     */   {
/* 161 */     boolean blocking = true;
/* 162 */     skipChar('{');
/* 163 */     long length = Long.parseLong(readNumber());
/* 164 */     if ((peekChar() == 43) && (extensionEnabled("LITERAL+"))) {
/* 165 */       skipChar('+');blocking = false;
/*     */     }
/* 167 */     skipChar('}');
/*     */     
/*     */ 
/* 170 */     if (getCurrentLine().length() != this.offset) {
/* 171 */       throw new ImapParseException(this.tag, "extra characters after literal declaration");
/*     */     }
/* 173 */     boolean lastPart = this.index == this.parts.size() - 1;
/* 174 */     if ((lastPart) || ((this.index == this.parts.size() - 2) && (this.literalCounter != -1L))) {
/* 175 */       if (this.literalCounter == -1L) {
/* 176 */         if (!isAppend()) {
/* 177 */           incrementSize(length);
/*     */         }
/* 179 */         checkSize(length);
/* 180 */         this.literalCounter = length;
/*     */       }
/* 182 */       if ((!blocking) && (this.input.available() >= this.literalCounter)) {
/* 183 */         continuation();
/*     */       } else {
/* 185 */         throw new ImapContinuationException((blocking) && (lastPart));
/*     */       }
/*     */     }
/* 188 */     this.index += 1;
/* 189 */     Literal result = getCurrentBuffer();
/* 190 */     this.index += 1;
/* 191 */     this.offset = 0;
/* 192 */     return result;
/*     */   }
/*     */   
/*     */   void incrementSize(long increment) {
/* 196 */     this.requestSize += increment;
/* 197 */     if (this.requestSize > this.mHandler.config.getMaxRequestSize()) {
/* 198 */       this.maxRequestSizeExceeded = true;
/*     */     }
/*     */   }
/*     */   
/*     */   boolean isMaxRequestSizeExceeded() {
/* 203 */     return this.maxRequestSizeExceeded;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   void addPart(ImapRequest.Part part)
/*     */   {
/* 212 */     if ((!this.maxRequestSizeExceeded) || (this.parts.isEmpty())) {
/* 213 */       super.addPart(part);
/*     */     }
/*     */   }
/*     */   
/*     */   final class ImapTerminatedException
/*     */     extends ImapParseException
/*     */   {
/*     */     private static final long serialVersionUID = 6105950126307803418L;
/*     */     
/*     */     ImapTerminatedException() {}
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/imap/TcpImapRequest.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */